home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / 32QUERY.PAK / DISPLAY.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  29KB  |  812 lines

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. #include "query.h"
  4.  
  5. static DBIResult SetupFields(CURProps TblProps, pFLDDesc pFldDescs,
  6.                              ppCHAR pszField, UINT16 uDefLength);
  7. static DBIResult GetFields(hDBICur hCur, pFLDDesc pFldDescs,
  8.                            pBYTE pRecBuf, CHAR** pszField,
  9.                            UINT16 uDefLength);
  10. static DBIResult FormatDate(DBIDATE Date, pCHAR szDate);
  11. static DBIResult FormatTime(TIME Time, pCHAR szDate);
  12. static DBIResult FormatTimeStamp(TIMESTAMP TimeStamp, pCHAR szTime);
  13.  
  14. #define         MAXLEN 50
  15.  
  16. //===============================================================
  17. //  Name:   Cls(pStr);
  18. //
  19. //  Input:  None
  20. //
  21. //  Return: None
  22. //
  23. //  Description:
  24. //          Clears the Result Edit control.
  25. //================================================================
  26. void
  27. Cls (void)
  28. {
  29.     SendDlgItemMessage(hMainWnd,
  30.                        IDC_RESULT_EDIT, WM_SETTEXT,
  31.                        0, (LPARAM)(LPCSTR)"");
  32. }
  33.  
  34. //===============================================================
  35. //  Function:
  36. //          Screen(pszMsg);
  37. //
  38. //  Input:  pszMsg  - String to display
  39. //
  40. //  Return: None
  41. //
  42. //  Description:
  43. //          Echo a message.
  44. //===============================================================
  45. void
  46. Screen (pCHAR pszMsg)
  47. {
  48.     pCHAR   pszBuf;
  49.  
  50.     if (pszMsg)
  51.     {
  52.         // Dump the string and output a CR+LF.
  53.         pszBuf = (pCHAR) malloc(lstrlen(pszMsg) + 3);
  54.         wsprintf(pszBuf, "%s\r\n", pszMsg);
  55.         SendDlgItemMessage(hMainWnd,
  56.                            IDC_RESULT_EDIT, EM_REPLACESEL,
  57.                            0, (LPARAM)(LPCSTR)pszBuf);
  58.         free(pszBuf);
  59.     }
  60. }
  61.  
  62. //==============================================================
  63. //  Function:
  64. //          ChkRslt(rslt, pMsg);
  65. //
  66. //  Input:  rslt - Return code from IDAPI
  67. //          pMsg - Null terminated message
  68. //
  69. //  Return: IDAPI return code passed in
  70. //
  71. //  Description:
  72. //          This will echo an error message if the expected
  73. //          result does not equal the actual result. The output will be
  74. //          echoed to the screen.
  75. //===============================================================
  76. DBIResult
  77. ChkRslt (DBIResult rslt, pCHAR pMsg)
  78. {
  79.     static CHAR szOutputErrorString[(DBIMAXMSGLEN * 6) + 81];
  80.  
  81.     // Echo only if actual result doesn't equal expected result.
  82.     if (rslt != DBIERR_NONE)
  83.     {
  84.         // Get as much error information as possible.
  85.         GetErrorInformation(szOutputErrorString);
  86.         Screen(szOutputErrorString);
  87.         sprintf(szOutputErrorString, "        Function: %s", pMsg);
  88.     }
  89.     return rslt;
  90. }
  91.  
  92. //=====================================================================
  93. //  Function:
  94. //          DisplayTable();
  95. //
  96. //  Input:  The cursor handle - which table to access
  97. //          DisplayNRecs      - How many records to display
  98. //                            - 0 = all records in the table
  99. //
  100. //  Return: Result of displaying the records in the table
  101. //
  102. //  Descrption:
  103. //          This function will display all records in the table referenced
  104. //          by the cursor. This function is used to display
  105. //          in-memory and scema tables which do not support
  106. //          the use of ReadBlock ( which is used in DislpayTable )
  107. //
  108. //  Note:   This function will only display the columns
  109. //          correctly when using a fixed pitch font.
  110. //=====================================================================
  111. DBIResult
  112. DisplayTable (hDBICur hCur, UINT32 uDisplayNRecs)
  113. {
  114.     DBIResult   rslt;               // IDAPI function return value
  115.     CURProps    TblProps;           // Table Properties
  116.     pFLDDesc    pFldDescs;          // List of fields
  117.     pBYTE       pRecBuf;            // Record Buffer
  118.     ppCHAR      pszField;           // Array to contain the fields of the
  119.                                     // table.
  120.     CHAR        szFormat[1600] =""; // Contains an entire record (row)
  121.     CHAR        szTemp[MAXLEN] =""; // Temporary variable for reading data
  122.     UINT16      uFldNum;            // Loop variable
  123.     UINT32      uCurCountRec=0;     // Counter to keep track of how many
  124.                                     // records have been displayed
  125.     const UINT16 uDefLength = 15;   // Default size of a field
  126.  
  127.     if ((rslt = DBIErr(DbiGetCursorProps(hCur, &TblProps)))
  128.          != DBIERR_NONE)
  129.     {
  130.         return rslt;
  131.     }
  132.  
  133.     // Allocate space for the Record Buffer.
  134.     if((pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE)))
  135.        == NULL)
  136.     {
  137.         return DBIERR_NOMEMORY;
  138.     }
  139.  
  140.     // Allocate enough space to contain information (Field Descriptors)
  141.     //   about all the fields in the answer table.
  142.     if ((pFldDescs = (pFLDDesc)malloc(TblProps.iFields * sizeof(FLDDesc)))
  143.         == NULL)
  144.     {
  145.         free(pRecBuf);
  146.         return DBIERR_NOMEMORY;
  147.     }
  148.  
  149.     // Get information about the fields.
  150.     DBIErr(DbiGetFieldDescs(hCur, pFldDescs));
  151.  
  152.     // Allocate enough buffers to contain data from the fields in the
  153.     //   answer table. Also sets the width of non-fldZSTRING fields
  154.     //   (all data will be converted to Strings for display ).
  155.     if ((pszField = (ppCHAR)malloc(TblProps.iFields * sizeof(pCHAR)))
  156.         == NULL)
  157.     {
  158.         free(pRecBuf);
  159.         free(pFldDescs);
  160.         return DBIERR_NOMEMORY;
  161.     }
  162.  
  163.  
  164.     // Set up formatting for the fields.
  165.     SetupFields(TblProps, pFldDescs, pszField, uDefLength);
  166.  
  167.     // Display the names of the fields, aligned by column.
  168.     strcpy(szFormat,"\r\n        ");
  169.     for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++)
  170.     {
  171.         sprintf(szTemp, "%-*s\t", pFldDescs[uFldNum].iUnits1 + 1,
  172.                  pFldDescs[uFldNum].szName);
  173.         strcat(szFormat, szTemp);
  174.     }
  175.  
  176.     // Display the header.
  177.     Screen(szFormat);
  178.  
  179.     // Get records from the table until the end of the table is reached
  180.     //   or the maximum number of records is reached.
  181.     //   Note that not all field types are supported. All supported field
  182.     //   types are displayed as Strings.
  183.     if (uDisplayNRecs == 0)
  184.     {
  185.         uDisplayNRecs = (UINT16)-1; // uDisplayNRecs is unsigned, so
  186.                                     //   -1 maximizes the value.
  187.     }
  188.  
  189.     while ((uCurCountRec < uDisplayNRecs) &&
  190.            ((rslt = DbiGetNextRecord(hCur, dbiNOLOCK, pRecBuf, NULL))
  191.             == DBIERR_NONE))
  192.     {
  193.         uCurCountRec++;
  194.  
  195.         // Fill the Record buffer with the field values.
  196.         GetFields(hCur, pFldDescs, pRecBuf, pszField, uDefLength);
  197.  
  198.         // Initialize szFormat to all zero's.
  199.         memset(szFormat, 0, sizeof(szFormat));
  200.  
  201.         // Add leading blank space to the record.
  202.         strcpy(szFormat,"        ");
  203.  
  204.         // Add each field to be displayed, making certain that the
  205.         //   columns line up.
  206.         for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++)
  207.         {
  208.             sprintf(szTemp, " %-*s\t", pFldDescs[uFldNum].iUnits1,
  209.             pszField[uFldNum]);
  210.             strcat(szFormat, szTemp);
  211.         }
  212.         // Display the record.
  213.         Screen(szFormat);
  214.     }
  215.  
  216.     // Expect the End-Of-File error - just means that there
  217.     //   aren't any more records in the table.
  218.     if (rslt == DBIERR_EOF)
  219.     {
  220.         rslt = DBIERR_NONE;
  221.     }
  222.  
  223.     // Clean up.
  224.     for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++)
  225.     {
  226.         free(pszField[uFldNum]);
  227.     }
  228.     free(pszField);
  229.     free(pFldDescs);
  230.     free(pRecBuf);
  231.  
  232.     return rslt;
  233. }
  234.  
  235. //=====================================================================
  236. //  Function:
  237. //          GetFields(hCur, pFldDescs, pRecBuf, pszField, uDefLength)
  238. //
  239. //  Input:  hCur        - Handle to the Cursor
  240. //          pFldDescs   - Field Descriptor
  241. //          pRecBuf     - Record buffer - contains the record from
  242. //                        which the field values are to be retrieved.
  243. //          pszField    - Fields in the table
  244. //          uDefLength  - Default length of a field
  245. //
  246. //  Return: Success of the operation.
  247. //
  248. //  Description:
  249. //          This function is used to extract all field values from
  250. //          a record and place them into an array of Strings.
  251. //=====================================================================
  252. DBIResult
  253. GetFields (hDBICur hCur, pFLDDesc pFldDescs, pBYTE pRecBuf,
  254.            ppCHAR pszField, UINT16 uDefLength)
  255. {
  256.     DBIResult   rslt;           // Return value from IDAPI functions
  257.     CURProps    TblProps;       // Properties of the table
  258.     UINT16      uFldNum;        // Loop Counter - used to determine the
  259.                                 //   current field.
  260.     CHAR        szTemp[MAXLEN] =""; // Temporary variable for reading data
  261.     UINT32      ulBlobSize;     // Size of the BLOB
  262.     DFLOAT      lfFloat;        // Float variable
  263.     BOOL        bIsBlank;       // Check if the field is blank
  264.     UINT16      uTmpLen;
  265.  
  266.     if ((rslt = DBIErr(DbiGetCursorProps(hCur, &TblProps)))
  267.         != DBIERR_NONE)
  268.     {
  269.         return rslt;
  270.     }
  271.  
  272.     // Get the field values from the record. Gets each field from
  273.     //   the table, placing the results in the pszField variable.
  274.     for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++)
  275.     {
  276.         switch (pFldDescs[uFldNum].iFldType)
  277.         {
  278.             case fldBYTES:
  279.             case fldZSTRING:
  280.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  281.                                     (pBYTE)pszField[uFldNum],
  282.                                     &bIsBlank));
  283.                 uTmpLen = (UINT16)(pFldDescs[uFldNum].iLen - 1);
  284.                 pszField[uFldNum][uTmpLen] = 0;
  285.                 break;
  286.             case fldFLOAT:
  287.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  288.                                     (pBYTE)szTemp, &bIsBlank));
  289.                 if (!bIsBlank)
  290.                 {
  291.                     if (pFldDescs[uFldNum].iSubType == fldstMONEY)
  292.                     {
  293.                         sprintf(pszField[uFldNum], "$%.2lf",
  294.                                 *(pDFLOAT)szTemp);
  295.                     }
  296.                     else
  297.                     {
  298.                         sprintf(pszField[uFldNum], "%.1lf",
  299.                                 *(pDFLOAT)szTemp);
  300.                     }
  301.                 }
  302.                 break;
  303.             case fldBCD:
  304.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  305.                                     (pBYTE)szTemp,
  306.                                     &bIsBlank));
  307.                 if (!bIsBlank)
  308.                 {
  309.                     DBIErr(DbiBcdToFloat((FMTBcd *)szTemp,
  310.                             &lfFloat));
  311.                     sprintf(pszField[uFldNum], "%.*lf",
  312.                             pFldDescs[uFldNum].iUnits2, lfFloat);
  313.                 }
  314.                 break;
  315.             case fldDATE:
  316.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  317.                                     (pBYTE)szTemp,
  318.                                     &bIsBlank));
  319.                 if (!bIsBlank)
  320.                 {
  321.                     // Format the date. FormatDate defined in
  322.                     //   SNIPTOOL.C.
  323.                     FormatDate(*(pDBIDATE)szTemp,
  324.                                pszField[uFldNum]);
  325.                 }
  326.                 break;
  327.             case fldTIME:
  328.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  329.                                     (pBYTE)&szTemp,
  330.                                     &bIsBlank));
  331.                 if (!bIsBlank)
  332.                 {
  333.                     FormatTime(*(pTIME)szTemp, pszField[uFldNum]);
  334.                 }
  335.                 break;
  336.             case fldTIMESTAMP:
  337.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  338.                                     (pBYTE)szTemp,
  339.                                     &bIsBlank));
  340.                 if (!bIsBlank)
  341.                 {
  342.                     FormatTimeStamp(*(pTIMESTAMP)szTemp,
  343.                                     pszField[uFldNum]);
  344.                 }
  345.                 break;
  346.            case fldINT16:
  347.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  348.                                     (pBYTE)szTemp,
  349.                                     &bIsBlank));
  350.                 if (!bIsBlank)
  351.                 {
  352.                     sprintf(pszField[uFldNum], "%d", *(INT16 *)szTemp);
  353.                 }
  354.                 break;
  355.             case fldUINT16:
  356.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  357.                                     (pBYTE)szTemp,
  358.                                     &bIsBlank));
  359.                 if (!bIsBlank)
  360.                 {
  361.                     sprintf(pszField[uFldNum], "%u", *(UINT16 *)szTemp);
  362.                 }
  363.                 break;
  364.             case fldINT32:
  365.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  366.                                     (pBYTE)szTemp,
  367.                                      &bIsBlank));
  368.                 if (!bIsBlank)
  369.                 {
  370.                     sprintf(pszField[uFldNum], "%ld",
  371.                             *(pINT32)szTemp);
  372.                 }
  373.                 break;
  374.             case fldUINT32:
  375.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  376.                                     (pBYTE)szTemp,
  377.                                      &bIsBlank));
  378.                 if (!bIsBlank)
  379.                 {
  380.                     sprintf(pszField[uFldNum], "%lu",
  381.                             *(pUINT32)szTemp);
  382.                 }
  383.                 break;
  384.             case fldBOOL:
  385.                 DBIErr(DbiGetField(hCur, (UINT16)(uFldNum+1), pRecBuf,
  386.                                     (pBYTE)szTemp,
  387.                                     &bIsBlank));
  388.                 if (!bIsBlank)
  389.                 {
  390.                     if (*(pBOOL)szTemp == 0)
  391.                     {
  392.                         strcpy(pszField[uFldNum], "No");
  393.                     }
  394.                     else
  395.                     {
  396.                         strcpy(pszField[uFldNum], "Yes");
  397.                     }
  398.                 }
  399.                 break;
  400.             case fldBLOB:
  401.                 // Display the first uDefLength characters of
  402.                 //   Memo BLOB fields.
  403.                 if (pFldDescs[uFldNum].iSubType == fldstMEMO)
  404.                 {
  405.                     DBIErr(DbiOpenBlob(hCur, pRecBuf,
  406.                                        (UINT16)(uFldNum + 1), dbiREADONLY));
  407.  
  408.                     // Determine the size of the BLOB.
  409.                     DBIErr(DbiGetBlobSize(hCur, pRecBuf,
  410.                                           (UINT16)(uFldNum + 1), &ulBlobSize));
  411.  
  412.                     // Determine the maximum amount to read.
  413.                     ulBlobSize = min(ulBlobSize, (UINT32)uDefLength-2);
  414.  
  415.                     // Get the BLOB from the table.
  416.                     DBIErr(DbiGetBlob(hCur, pRecBuf,
  417.                                       (UINT16)(uFldNum + 1), 0,
  418.                                       ulBlobSize,
  419.                                       (pBYTE)pszField[uFldNum],
  420.                                       &ulBlobSize));
  421.  
  422.                     // Add the NULL terminator to the string.
  423.                     pszField[uFldNum][(UINT16)ulBlobSize]
  424.                      = 0;
  425.  
  426.                     // Free the blob from memory.
  427.                     DBIErr(DbiFreeBlob(hCur, pRecBuf,
  428.                                        (UINT16)(uFldNum + 1)));
  429.                 }
  430.                 else
  431.                 {
  432.                     strcpy(pszField[uFldNum], "Can't Display");
  433.                 }
  434.                 break;
  435.             default:
  436.                 strcpy(pszField[uFldNum], "Can't Display");
  437.                 break;
  438.         }
  439.         // Initialize the string in case the field was blank.
  440.         if (bIsBlank)
  441.         {
  442.             strcpy(pszField[uFldNum], "");
  443.             bIsBlank = FALSE;
  444.         }
  445.     }
  446.     return DBIERR_NONE;
  447. }
  448.  
  449. //=====================================================================
  450. //  Function:
  451. //          SetupFields(TblProps, pFldDescs, pszField, uDefLength)
  452. //
  453. //  Input:  TblProps    - Properties of the Table
  454. //          pFldDescs   - Field Descriptor
  455. //          pszField    - Fields in the table
  456. //          uDefLength  - Default length of a field
  457. //
  458. //  Return: Success of the operation.
  459. //
  460. //  Description:
  461. //          This function sets up the formatting of the fields.
  462. //=====================================================================
  463. DBIResult
  464. SetupFields (CURProps TblProps, pFLDDesc pFldDescs, CHAR** pszField,
  465.              UINT16 uDefLength)
  466. {
  467.     UINT16      uFldNum;            // Loop variable
  468.  
  469.     for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++)
  470.     {
  471.         // Allocate enough space to contain the data in each field.
  472.         switch (pFldDescs[uFldNum].iFldType)
  473.         {
  474.             case fldBYTES:
  475.             case fldZSTRING:
  476.                 pszField[uFldNum] = (pCHAR)malloc(((pFldDescs[uFldNum].iLen +1)
  477.                                                   * sizeof(CHAR)));
  478.                 if (MAXLEN - 4 < pFldDescs[uFldNum].iLen)
  479.                 {
  480.                     pFldDescs[uFldNum].iUnits1 = MAXLEN-4;
  481.                     pFldDescs[uFldNum].iLen    = MAXLEN-3;
  482.                 }
  483.                 // Adjust if the field is smaller than it's description.
  484.                 if (pFldDescs[uFldNum].iLen <
  485.                     strlen(pFldDescs[uFldNum].szName))
  486.                 {
  487.                     pFldDescs[uFldNum].iUnits1 =
  488.                                    (UINT16)strlen(pFldDescs[uFldNum].szName);
  489.                     pFldDescs[uFldNum].iLen    =
  490.                                    (UINT16)(pFldDescs[uFldNum].iUnits1 + 1);
  491.                 }
  492.                 break;
  493.             case fldFLOAT:
  494.             case fldDATE:
  495.             case fldINT16:
  496.             case fldUINT16:
  497.             case fldINT32:
  498.             case fldUINT32:
  499.             case fldBOOL:
  500.             case fldBLOB:
  501.             case fldBCD:
  502.                 pszField[uFldNum] = (pCHAR)malloc(((uDefLength + 1)*
  503.                                                   sizeof(CHAR)));
  504.                 // Set the Width of the field as it will be displayed.
  505.                 pFldDescs[uFldNum].iUnits1 = uDefLength;
  506.                 pFldDescs[uFldNum].iLen    = (UINT16)(uDefLength + 1);
  507.                 // Adjust if the field is smaller than it's description.
  508.                 if (pFldDescs[uFldNum].iLen <
  509.                     strlen(pFldDescs[uFldNum].szName))
  510.                 {
  511.                     pFldDescs[uFldNum].iUnits1 =
  512.                                     (UINT16)strlen(pFldDescs[uFldNum].szName);
  513.                     pFldDescs[uFldNum].iLen    =
  514.                                      (UINT16)(pFldDescs[uFldNum].iUnits1 + 1);
  515.                 }
  516.                 break;
  517.             case fldTIMESTAMP:
  518.                 pszField[uFldNum] = (pCHAR)malloc((37 *
  519.                                                   sizeof(CHAR)));
  520.                 // Set the Width of the field as it will be displayed.
  521.                 pFldDescs[uFldNum].iUnits1 = 36;
  522.                 pFldDescs[uFldNum].iLen    = 37;
  523.                 // Adjust if the field is smaller than it's description.
  524.                 if (pFldDescs[uFldNum].iLen <
  525.                     strlen(pFldDescs[uFldNum].szName))
  526.                 {
  527.                     pFldDescs[uFldNum].iUnits1 =
  528.                                    (UINT16)strlen(pFldDescs[uFldNum].szName);
  529.                     pFldDescs[uFldNum].iLen    =
  530.                                    (UINT16)(pFldDescs[uFldNum].iUnits1 + 1);
  531.                 }
  532.                 break;
  533.             case fldTIME:
  534.                 pszField[uFldNum] = (pCHAR)malloc((21 *
  535.                                                   sizeof(CHAR)));
  536.                 // Set the Width of the field as it will be displayed.
  537.                 pFldDescs[uFldNum].iUnits1 = 20;
  538.                 pFldDescs[uFldNum].iLen    = 21;
  539.                   // Adjust if the field is smaller than it's description.
  540.                 if (pFldDescs[uFldNum].iLen <
  541.                     strlen(pFldDescs[uFldNum].szName))
  542.                 {
  543.                     pFldDescs[uFldNum].iUnits1 =
  544.                                     (UINT16)strlen(pFldDescs[uFldNum].szName);
  545.                     pFldDescs[uFldNum].iLen    =
  546.                                     (UINT16)(pFldDescs[uFldNum].iUnits1 + 1);
  547.                 }
  548.               break;
  549.             default:
  550.                 // This field size will hold the 'Not Supported'
  551.                 //   message.
  552.                 pszField[uFldNum] = (pCHAR)malloc(((uDefLength + 1) *
  553.                                                   sizeof(CHAR)));
  554.                 // Set the width of the field as it will be displayed.
  555.                 pFldDescs[uFldNum].iUnits1 = uDefLength;
  556.                 pFldDescs[uFldNum].iLen    = (UINT16)(uDefLength + 1);
  557.                 break;
  558.         }
  559.     }
  560.  
  561.     return DBIERR_NONE;
  562. }
  563.  
  564.  
  565. //=====================================================================
  566. //  Function:
  567. //          FormatDate(Date, szDate)
  568. //
  569. //  Input:  Date     - Date which needs to be formatted
  570. //          szDate   - String to contain the formatted date
  571. //
  572. //  Return: Result returned from DbiPutField().
  573. //
  574. //  Description:
  575. //          This function is used to format date fields
  576. //=====================================================================
  577. DBIResult
  578. FormatDate (DBIDATE Date, pCHAR szDate)
  579. {
  580.     DBIResult   rslt;       // Return Value from IDAPI
  581.     FMTDate     fmtDate;    // Date Format
  582.     UINT16      uDay;       // Day portion of date
  583.     UINT16      uMonth;     // Month portion of date
  584.     INT16       iYear;      // Year portion of date
  585.  
  586.     // Get the formatting of the Date.
  587.     DBIErr(DbiGetDateFormat(&fmtDate));
  588.  
  589.     // Decode the date.
  590.     rslt = DBIErr(DbiDateDecode(Date, &uMonth, &uDay, &iYear));
  591.  
  592.     // Determine if date should be displayed year based.
  593.     if (!(fmtDate.bFourDigitYear) &&
  594.         (fmtDate.bYearBiased))
  595.     {
  596.         iYear = (UINT16)(iYear + 1900);
  597.     }
  598.  
  599.     if (!(fmtDate.bFourDigitYear))
  600.     {
  601.         iYear = (UINT16)(iYear - 1900);
  602.     }
  603.  
  604.     // Make certain the seperator is not the
  605.     //   escape character.
  606.     if (!strcmp(fmtDate.szDateSeparator, "\\"))
  607.     {
  608.         strcpy(fmtDate.szDateSeparator, "/");
  609.     }
  610.  
  611.     // Format the date.
  612.     switch(fmtDate.iDateMode)
  613.     {
  614.         // MM/DD/YY - Month, Day, Year.
  615.         case 0:
  616.             sprintf(szDate,
  617.                     "%0*d%s%0*d%s%0*d",
  618.                     1 + fmtDate.bMonthLeadingZero,
  619.                     uMonth,
  620.                     fmtDate.szDateSeparator,
  621.                     1 + fmtDate.bDayLeadingZero,
  622.                     uDay,
  623.                     fmtDate.szDateSeparator,
  624.                     2,
  625.                     iYear);
  626.             break;
  627.         // DD/MM/YY - Day, Month, Year
  628.         case 1:
  629.             sprintf(szDate,
  630.                     "%0*d%s%0*d%s%0*d",
  631.                     1 + fmtDate.bDayLeadingZero,
  632.                     uDay,
  633.                     fmtDate.szDateSeparator,
  634.                     1 + fmtDate.bMonthLeadingZero,
  635.                     uMonth,
  636.                     fmtDate.szDateSeparator,
  637.                     2,
  638.                     iYear);
  639.             break;
  640.         // YY/MM/DD - Year, Month, Day
  641.         case 2:
  642.             sprintf(szDate,
  643.                     "%0*d%s%0*d%s%0*d",
  644.                     2,
  645.                     iYear,
  646.                     fmtDate.szDateSeparator,
  647.                     1 + fmtDate.bMonthLeadingZero,
  648.                     uMonth,
  649.                     fmtDate.szDateSeparator,
  650.                     1 + fmtDate.bDayLeadingZero,
  651.                     uDay);
  652.             break;
  653.     }
  654.     return rslt;
  655. }
  656.  
  657. //=====================================================================
  658. //  Function:
  659. //          FormatTime(Time, szTime)
  660. //
  661. //  Input:  Time     - Time which needs to be formatted
  662. //          szTime   - String to contain the formatted time
  663. //
  664. //  Return: Result returned from DbiPutField().         +
  665. //
  666. //  Description:
  667. //          This function is used to format Time fields.
  668. //=====================================================================
  669. DBIResult
  670. FormatTime (TIME Time, pCHAR szTime)
  671. {
  672.     DBIResult   rslt;       // Return value from IDAPI functions
  673.     FMTTime     fmtTime;    // Time format
  674.     UINT16      uHour;      // Hour portion of the time
  675.     UINT16      uMinute;    // Minute portion of the time
  676.     UINT16      uMilSec;    // Second portion (in ms) of the time
  677.     UINT16      uIsAm;      // Is Time AM?
  678.     CHAR        szTemp[10]; // Temp buffer, used for AM, PM string
  679.  
  680.     // Get the formatting of the Time.
  681.     DBIErr(DbiGetTimeFormat(&fmtTime));
  682.  
  683.     // Decode the time.
  684.     rslt = DBIErr(DbiTimeDecode(Time, &uHour, &uMinute, &uMilSec));
  685.  
  686.     // Make certain the seperator is not the
  687.     //   escape character.
  688.     if (fmtTime.cTimeSeparator == '\\')
  689.     {
  690.         fmtTime.cTimeSeparator  = '/';
  691.     }
  692.  
  693.     // Check if time should be displayed in 12 or 24 hour format.
  694.     if (fmtTime.bTwelveHour)
  695.     {
  696.         // Temporary variable used to determine if the time is AM or PM.
  697.         uIsAm = uHour;
  698.         uHour = (UINT16)(uHour % 12);
  699.         if (uHour == 0)
  700.         {
  701.             uHour = 12;
  702.         }
  703.         // If AM, set uIsAm to TRUE, else set uIsAm to 0.
  704.         if (uIsAm == uHour)
  705.         {
  706.             uIsAm = 1;
  707.         }
  708.         else
  709.         {
  710.             uIsAm = 0;
  711.         }
  712.     }
  713.  
  714.     // Format the hour and minute of the time.
  715.     wsprintf(szTime, "%2u%c%02u",
  716.              uHour,
  717.              fmtTime.cTimeSeparator,
  718.              uMinute);
  719.  
  720.     // Determine if seconds are to be displayed.
  721.     if (fmtTime.bSeconds)
  722.     {
  723.         wsprintf(szTemp, "%c%02u",
  724.                  fmtTime.cTimeSeparator,
  725.                  (uMilSec / 1000));
  726.  
  727.         strcat(szTime, szTemp);
  728.  
  729.         // Determine if milliseconds are to be displayed.
  730.         if (fmtTime.bMilSeconds)
  731.         {
  732.             wsprintf(szTemp, "%c%03u",
  733.                      fmtTime.cTimeSeparator,
  734.                      (uMilSec % 1000));
  735.             strcat(szTime, szTemp);
  736.         }
  737.     }
  738.  
  739.     // Add a string to the time if the time is 12-hour.
  740.     if (fmtTime.bTwelveHour)
  741.     {
  742.         strcat(szTime, " ");
  743.         if (uIsAm)
  744.         {
  745.             strcat(szTime, fmtTime.szAmString);
  746.         }
  747.         else // otherwise it's PM
  748.         {
  749.             strcat(szTime, fmtTime.szPmString);
  750.         }
  751.     }
  752.  
  753.     return rslt;
  754. }
  755.  
  756. //=====================================================================
  757. //  Function:
  758. //          FormatTimeStamp(TimeStamp, szTimeStamp)
  759. //
  760. //  Input:  TimeStamp     - Time which needs to be formatted
  761. //          szTimeStamp   - String to contain the formatted time
  762. //
  763. //  Return: Result returned from DbiPutField().
  764. //
  765. //  Description:
  766. //          This function is used to format TimeStamp fields.
  767. //=====================================================================
  768. DBIResult
  769. FormatTimeStamp (TIMESTAMP TimeStamp, pCHAR szTimeStamp)
  770. {
  771.     DBIResult   rslt;       // Return value from IDAPI functions
  772.     TIME        Time;       // Time portion of the TimeStamp
  773.     DBIDATE     Date;       // Date portion of the TimeStamp
  774.     CHAR        szDate[15]; // Date string
  775.     CHAR        szTime[20]; // Time String
  776.  
  777.     // Get the date and time components
  778.     rslt = DBIErr(DbiTimeStampDecode(TimeStamp, &Date, &Time));
  779.  
  780.     // Get the Date format
  781.     FormatDate(Date, szDate);
  782.     // Get the Time format
  783.     FormatTime(Time, szTime);
  784.  
  785.     // Format the TimeStamp
  786.     wsprintf(szTimeStamp, "%s, %s", szTime, szDate);
  787.  
  788.     return rslt;
  789. }
  790.  
  791.  
  792. //======================================================================
  793. //  Function:
  794. //          DisplayProgress(szProgress)
  795. //
  796. //  Input:  szProgress - String to display
  797. //
  798. //  Return: None
  799. //
  800. //  Description:
  801. //          Displays progress information in the progress static control
  802. //          of the main dialog.
  803. //======================================================================
  804. void
  805. DisplayProgress (char *szProgress)
  806. {
  807.     SendDlgItemMessage(hMainWnd, IDS_PROGRESS,
  808.                        WM_SETTEXT, 0, (LPARAM) szProgress);
  809. }
  810.  
  811.  
  812.